package handler

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
	"ulcdkey/conf"
	"ulcdkey/db"
	"ulcdkey/tool"

	"github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo/v4"
)

const (
	webAuthLogonUrl  = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wwde61fb5cd7fb828d&redirect_uri=%s&response_type=code&scope=snsapi_base#wechat_redirect"
	scanCodeLogonUrl = "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=wwde61fb5cd7fb828d&agentid=%s&redirect_uri=%s"
	userInfoUrl      = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo"
)

// 统一的响应结果
type ResponseResult struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data,omitempty"`
}

// 跨域
func CorssDoMain(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		c.Response().Header().Set("Access-Control-Allow-Origin", "*")
		c.Response().Header().Set("Access-Control-Allow-Methods", "*")
		c.Response().Header().Set("Access-Control-Allow-Headers", "Content-type,token,x-requested-with,Authorization,megaDataPlatform")
		c.Response().Header().Set("Access-Control-Allow-Credentials", "true")
		c.Response().Header().Set("Access-Control-Max-Age", "86400")
		return next(c)
	}
}

//校验接口权限
func CheckRole(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		var r ResponseResult
		uid := tool.GetUid(c)
		/*byte1, _ := json.Marshal(db.TempUser)
		log.Println(string(byte1))*/
		user, ok := db.UserList[uid]
		if !ok {
			r.Code = -1
			r.Msg = "无权限操作"
			return c.JSON(200, r)
		}

		if user.Status == 1 {
			r.Code = -1
			r.Msg = "用户已被禁用"
			return c.JSON(200, r)
		}
		return next(c)
	}
}

//更新用户缓存
func RefreshCacheUsers(c echo.Context) (err error) {

	var r ResponseResult

	u := new(db.User)

	err = u.CacheUsers()
	if err != nil {

		r.Code = -1
		r.Msg = "缓存失败:" + err.Error()
		return c.JSON(200, r)

	}

	return c.JSON(200, r)
}

func RenderIndex(c echo.Context) error {
	return c.Render(200, "public/dist/index.html", nil)
}

//企业微信登录
func RenderLogin(c echo.Context) error {

	/* 构建企业微信登陆 */
	// 1.企业微信自动授权登陆
	// 2.电脑扫码登陆
	path := c.QueryParam("redirect")
	userAgent := c.Request().Header.Get("User-Agent")
	//log.Println("userAgent:", userAgent)
	if strings.Contains(userAgent, "QQBrowser") || !strings.Contains(userAgent, "Windows") || strings.Contains(userAgent, "wxwork") {
		return c.Redirect(302, fmt.Sprintf(webAuthLogonUrl, url.QueryEscape(conf.Conf.LoginRedirectUri+"?path="+path)))
	} else {
		return c.Redirect(302, fmt.Sprintf(scanCodeLogonUrl, strconv.Itoa(qyWx.AgentId), url.QueryEscape(conf.Conf.LoginRedirectUri+"?path="+path)))
	}

	return nil
}

// 身份获取连接
func RenderAuth(c echo.Context) error {

	code := c.QueryParam("code")
	path := c.QueryParam("path")
	userId := c.QueryParam("userId")
	if path == "" {
		path = "/index"
	}
	if userId == "" {
		var err error
		userId, err = qyWx.GetUserInfo(code)
		if err != nil {
			return c.JSON(200, &ResponseResult{Code: -1, Msg: err.Error()})
		}
	}
	nUser := new(db.User)
	u, err := nUser.GetUserByWxUserId(userId)
	if err != nil {
		return c.JSON(200, &ResponseResult{Code: -1, Msg: err.Error()})
	}
	if u.Status == -1 {
		return c.JSON(200, &ResponseResult{Code: -1, Msg: "没有登陆权限"})
	}
	token := jwt.New(jwt.SigningMethodHS256)
	claims := token.Claims.(jwt.MapClaims)
	claims["id"] = u.Id
	claims["name"] = u.Name
	claims["exp"] = time.Now().Add(time.Hour * 2400000).Unix()

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte(conf.Conf.JwtSecret))
	if err != nil {
		return c.JSON(200, &ResponseResult{Code: -1, Msg: err.Error()})
	}
	c.SetCookie(&http.Cookie{Name: "Admin-Token", Value: t})
	log.Println(userId, "login success")
	return c.Redirect(302, path)
}

func RenderAccountLogin(c echo.Context) error {
	return c.Redirect(302, "/#/login")
}

func Login(c echo.Context) error {
	var r ResponseResult
	username := c.FormValue("username")
	password := c.FormValue("password")

	user := new(db.User)
	//检查账号
	u, err := user.CheckUser(username, tool.MD5(password))

	if err != nil {
		log.Println(err)
		r.Code = -1
		r.Msg = "登录失败,err=" + err.Error()
		return c.JSON(200, r)
	}

	// Create token
	token := jwt.New(jwt.SigningMethodHS256)

	// Set claims
	claims := token.Claims.(jwt.MapClaims)
	claims["id"] = u.Id
	claims["name"] = u.Name
	claims["exp"] = time.Now().Add(time.Hour * 240).Unix()

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte(conf.Conf.JwtSecret))
	if err != nil {

		r.Code = -1
		r.Msg = "登录失败,err=" + err.Error()
		return c.JSON(200, r)
	}

	r.Data = map[string]string{
		"token": t,
	}

	return c.JSON(200, r)
}

// 获取用户详情
func GetUserInfo(c echo.Context) error {
	var r ResponseResult
	t := time.Now()
	uid := tool.GetUid(c)

	user := new(db.User)
	u, err := user.GetUserById(uid)

	if err != nil {
		log.Println(err)
		r.Code = -1
		r.Msg = "获取数据失败,err=" + err.Error()
		return c.JSON(200, r)
	}

	r.Data = u
	log.Println(c.Request().URL, "uid =", uid, "【耗时:", time.Now().Sub(t).Seconds(), "s】")
	return c.JSON(200, r)
}

//获取路由表
func GetMenuByRole(c echo.Context) error {

	var r ResponseResult
	t := time.Now()
	uid := tool.GetUid(c)

	user := new(db.User)
	ms, err := user.GetMenuByRole(uid)

	if err != nil {
		log.Println(err)
		r.Code = -1
		r.Msg = "获取数据失败,err=" + err.Error()
		return c.JSON(200, r)
	}
	r.Data = ms
	log.Println(c.Request().URL, "uid =", uid, "【耗时:", time.Now().Sub(t).Seconds(), "s】")
	return c.JSON(200, r)
}

// 获取用户列表
func GetUsers(c echo.Context) error {
	var r ResponseResult
	t := time.Now()
	uid := tool.GetUid(c)

	user := new(db.User)
	us, err := user.GetUsers()
	if err != nil {
		r.Code = -1
		r.Msg = "获取数据失败,err=" + err.Error()
		return c.JSON(200, r)
	}
	r.Data = us
	log.Println(c.Request().URL, "uid =", uid, "【耗时:", time.Now().Sub(t).Seconds(), "s】")
	return c.JSON(200, r)
}

// 修改用户
func ModUser(c echo.Context) (err error) {
	var r ResponseResult
	t := time.Now()
	uid := tool.GetUid(c)

	user := new(db.User)

	user.Id, err = strconv.Atoi(c.FormValue("id"))
	if err != nil {
		r.Code = -1
		r.Msg = "id 参数错误,err=" + err.Error()
		return c.JSON(200, r)
	}

	user.RoleId, err = strconv.Atoi(c.FormValue("roleId"))
	if err != nil {
		r.Code = -1
		r.Msg = "roleId 参数错误,err=" + err.Error()
		return c.JSON(200, r)
	}

	user.Status, err = strconv.Atoi(c.FormValue("status"))
	if err != nil {
		r.Code = -1
		r.Msg = "status 参数错误,err=" + err.Error()
		return c.JSON(200, r)
	}

	user.Name = c.FormValue("name")

	userInfo := tool.GetVisitUserInfo(c)

	err = user.ModUser(userInfo)
	if err != nil {
		r.Code = -1
		r.Msg = "更新失败,err=" + err.Error()
		return c.JSON(200, r)
	}
	log.Println(c.Request().URL, "uid =", uid, "【耗时:", time.Now().Sub(t).Seconds(), "s】")
	return c.JSON(200, r)
}
